<?php
/**
 * User: 784855684@qq.com
 * Date: 31/12/2017
 * Time: 17:37
 */
declare(strict_types=1);


namespace AppBundle\Utils;


use AppBundle\Entity\Material;
use AppBundle\Entity\Product;
use AppBundle\Throwable\MaterialEmptyException;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\ORM\EntityManager;

class ProductUtil extends EntityUtil
{

    /**
     * @param string $name
     * @param string $customer_name
     * @param string $description
     * @param array $materials
     * @param bool $autoFlush it will not auto flush when object created if set to false
     * @param bool $useTransaction it will not start a transaction inside the method if set to false
     * @return Product
     * @throws MaterialEmptyException
     * @throws \Doctrine\DBAL\ConnectionException
     */
    public function create(string $name, string $customer_name, string $description, array $materials = [], bool $autoFlush = true, bool $useTransaction = true)
    {
        $conn = null;
        if ($autoFlush and $useTransaction) {
            $conn = $this->em->getConnection();
            $conn->beginTransaction();
        }
        $product = new Product();
        $price = 0.0;
        foreach ($materials as $material) {
            /** @var Material $material */
            $product->addMaterial($material);
            $inventory = $material->getInventory();
            if (!$inventory) {
                if ($autoFlush and $useTransaction) $conn->rollBack();
                throw new MaterialEmptyException("The material '{$material->getName()}' is stock is empty.", 4004);
            } # For simplicity, when material is added to product, only one piece is taken from stock.
            $material->setInventory($inventory - 1);
            $price += $material->getPrice();
        }
        $product->setName($name);
        $product->setCustomerName($customer_name);
        $product->setDescription($description);
        $product->setPrice($price);
        $product->setAddTime(new \DateTime());
        $product->setRemove(0);

        $this->em->persist($product);
        $autoFlush and $this->em->flush();
        if ($autoFlush and $useTransaction) $conn->commit();
        return $product;
    }
}